package com.mine.dubbo.netty;

import com.mine.dubbo.netty.model.Request;
import com.mine.dubbo.netty.model.Response;
import lombok.extern.log4j.Log4j2;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Log4j2
public class DefaultFuture {
    private final static ConcurrentHashMap<Long, DefaultFuture> MAP = new ConcurrentHashMap<>();
    private final Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private volatile Response response;

    public DefaultFuture(Request request) {
        MAP.put(request.getId(), this);
    }

    public Response get() {
        lock.lock();
        try {
            while (!done()) {
                condition.await();
            }
        } catch (Exception e) {
            log.error("{}", e);
        } finally {
            lock.unlock();
        }
        return response;
    }

    private boolean done() {
        if (response != null) {
            return true;
        }
        return false;
    }

    public static void receive(Response response) {
        DefaultFuture defaultFuture = MAP.remove(response.getId());
        if (defaultFuture != null) {
            defaultFuture.lock.lock();
            defaultFuture.response = response;
            defaultFuture.condition.signal();
            defaultFuture.lock.unlock();
        }
    }
}
